package com.inspur.edp.formserver.vmmanager.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.exceptions.CefException;
import com.inspur.edp.cef.designtime.api.json.Variable.CommonVariableDeserializer;
import com.inspur.edp.cef.designtime.api.json.Variable.CommonVariableSerializer;
import com.inspur.edp.cef.designtime.api.variable.CommonVariable;
import com.inspur.edp.formserver.viewmodel.common.ViewModelErrorCodes;
import com.inspur.edp.formserver.viewmodel.util.UpdateVoVariableUtil;
import com.inspur.edp.formserver.vmmanager.exception.VmManagerException;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

public class UpdateVariableWithUdtService {
  private String errorCode = "UpdateVariableWithUdtService";
  
  public static UpdateVariableWithUdtService getInstance() {

    return new UpdateVariableWithUdtService();
  }

  /**
   根据选中的udt元数据,更新多值udt字段信息
   更新ChildElements,Mapping
   说明：若为字段上选择udt，所有属性带出；若为加载更新，则仅更新使用方式为【约束】的属性。

   @return 更新后字段的json序列化
   */
  public  String updateVariableWithRefUdt(String refUdtId, String path, String udtElementJson, boolean isFirstChoose)
  {
    RefCommonService metadataService = SpringBeanUtils.getBean(RefCommonService.class);

    GspMetadata refUdtMetadata = metadataService.getRefMetadata(refUdtId);

    CommonVariable commonVariable;
    try {
      commonVariable= getMapper().readValue(udtElementJson,CommonVariable.class);
    } catch (JsonProcessingException e) {
     throw new CefException(ViewModelErrorCodes.GSP_BFF_ELEMENT_0001,"udt字段反序列化失败！",e,ExceptionLevel.Error,true);
    }

    IMetadataContent content = refUdtMetadata.getContent();
    if (content instanceof UnifiedDataTypeDef)
    {
      UpdateVoVariableUtil util = new UpdateVoVariableUtil();
      util.UpdateElementWithRefUdt(commonVariable, (UnifiedDataTypeDef) content, isFirstChoose);
    }
		else
    {
      throw new VmManagerException("",errorCode, "未定义的业务字段元数据类型。",null, ExceptionLevel.Error,false);
    }

		String eleJson;
    try {
      eleJson=getMapper().writeValueAsString(commonVariable);
    } catch (JsonProcessingException e) {
      throw new CefException(ViewModelErrorCodes.GSP_BFF_ELEMENT_0001,"udt字段序列化失败！",e,ExceptionLevel.Error,true);
    }
    return eleJson;
  }
  public  String updateVariableWithRefUdt(JsonNode node, String refUdtId, String path, String udtElementJson, boolean isFirstChoose) {

    GspMetadata refUdtMetadata = WebControllerService.getMetadata(node,path,"",refUdtId);
    CommonVariable commonVariable;
    try {
      commonVariable= getMapper().readValue(udtElementJson,CommonVariable.class);
    } catch (JsonProcessingException e) {
      throw new CefException(ViewModelErrorCodes.GSP_BFF_ELEMENT_0001,"udt字段反序列化失败！",e,ExceptionLevel.Error,true);
    }

    IMetadataContent content = refUdtMetadata.getContent();
    if (content instanceof UnifiedDataTypeDef)
    {
      UpdateVoVariableUtil util = new UpdateVoVariableUtil();
      util.UpdateElementWithRefUdt(commonVariable, (UnifiedDataTypeDef) content, isFirstChoose);
    }
    else
    {
      throw new VmManagerException("",errorCode, "未定义的业务字段元数据类型。",null, ExceptionLevel.Error,false);
    }

    String eleJson;
    try {
      eleJson=getMapper().writeValueAsString(commonVariable);
    } catch (JsonProcessingException e) {
      throw new CefException(ViewModelErrorCodes.GSP_BFF_ELEMENT_0001,"udt字段序列化失败！",e,ExceptionLevel.Error,true);
    }
    return eleJson;
  }
  private ObjectMapper getMapper(){

    ObjectMapper mapper=new ObjectMapper();
    SimpleModule module=new SimpleModule();
    module.addDeserializer(IGspCommonField.class, new CommonVariableDeserializer());
    module.addSerializer(IGspCommonField.class,new CommonVariableSerializer());
    mapper.registerModule(module);
    return  mapper;
  }
}
